
(1) RenameIdents()

声明S3泛型函数：
./seurat-object-4.1.4/R/generics.R:977:#' pbmc_small <- RenameIdents(pbmc_small, '0' = 'A', '2' = 'C')
./seurat-object-4.1.4/R/generics.R:980:RenameIdents <- function(object, ...) {
./seurat-object-4.1.4/R/generics.R:981:  UseMethod(generic = 'RenameIdents', object = object)


#' @return \code{RenameIdents}: An object with selected identity classes renamed
#'
#' @rdname Idents
#' @export RenameIdents
#' @aliases RenameIdent
#'
#' @examples
#' # Rename cell identity classes
#' # Can provide an arbitrary amount of idents to rename
#' levels(pbmc_small)
#' pbmc_small <- RenameIdents(pbmc_small, '0' = 'A', '2' = 'C')
#' levels(pbmc_small)
#'
RenameIdents <- function(object, ...) {
  UseMethod(generic = 'RenameIdents', object = object)
}




函数实现：
./seurat-object-4.1.4/R/seurat.R:1698:RenameIdents.Seurat <- function(object, ...) {


#' @rdname Idents
#' @export
#' @method RenameIdents Seurat
#'
RenameIdents.Seurat <- function(object, ...) {
  #(A1) 把用户输入的 list 或者 named vector 都转化为 list。详见本文3(3)
  ident.pairs <- tryCatch(
    expr = as.list(x = ...),
    error = function(e) {
      return(list(...))
    }
  )

  #(A2) 做输入校验，键值对，把 键 重新命名为 值
  # (B1)names() 不能为空
  if (is.null(x = names(x = ident.pairs))) {
    stop("All arguments must be named with the old identity class")
  }

  # (B2) 键值对中 值必须长度是1：新cluster只能有一个名字
  if (!all(sapply(X = ident.pairs, FUN = length) == 1)) {
    stop("Can only rename identity classes to one value")
  }
  # (B3) 提供的键值对的 键，必须都在 老的 levels 中
  if (!any(names(x = ident.pairs) %in% levels(x = object))) {
    stop("Cannot find any of the provided identities")
  }
  # (B4) 键值对 list: idents 及其对应的cell id
  cells.idents <- CellsByIdentities(object = object) # 该函数见(2)

  # (B5) 用户输入的键值对，遍历键
  for (i in rev(x = names(x = ident.pairs))) {
  	# 如果 键 i 不在 老的 cell idents 中，则警告，并进行下一轮遍历
    if (!i %in% names(x = cells.idents)) {
      warning("Cannot find identity ", i, call. = FALSE, immediate. = TRUE)
      next
    }
    # 如果 键i在 老的cell idents中，则把其对应的细胞 的 ident 更新
    Idents(object = object, cells = cells.idents[[i]]) <- ident.pairs[[i]]
  }

  return(object)
}







(2) CellsByIdentities() 返回键值对，ident 分组及其对应的 cell id

$ find . | grep "R$" | grep -v "testthat" | grep -v "notes" | grep -v "old/" | xargs grep -n "CellsByIdentities" 2>/dev/null --color=auto
./seurat-object-4.1.4/R/seurat.R:207:CellsByIdentities <- function(


#' Get cell names grouped by identity class
#'
#' @param object A Seurat object
#' @param idents A vector of identity class levels to limit resulting list to;
#' defaults to all identity class levels
#' @param cells A vector of cells to grouping to
#' @param return.null If no cells are request, return a \code{NULL};
#' by default, throws an error
#'
#' @return A named list where names are identity classes and values are vectors
#' of cells belonging to that class | 返回 named list，键值对中，键是level名，值是细胞向量
#'
#' @export
#'
#' @concept data-access
#'
#' @examples
#' CellsByIdentities(object = pbmc_small)
#'
CellsByIdentities <- function(
  object,
  idents = NULL, #限定某个 cluster
  cells = NULL, #限定 细胞
  return.null = FALSE #如果为空，设定为T，则返回null。否则，默认报错
) {
  #(A1) 限定细胞，参数没提供，就是全部细胞
  cells <- cells %||% colnames(x = object)
  # 细胞 与 对象的细胞 取交集
  cells <- intersect(x = cells, y = colnames(x = object))
  # 如果没细胞
  if (length(x = cells) == 0) {
    if (isTRUE(x = return.null)) {
      return(NULL)
    }
    stop("Cannot find cells provided")
  }

  #(A2) 限定类别，没提供，默认是全部 levels
  idents <- idents %||% levels(x = object)
  # 和 levels 做交集
  idents <- intersect(x = idents, y = levels(x = object))
  # 如果交集是空，报错
  if (length(x = idents) == 0) {
    stop("None of the provided identity class levels were found", call. = FALSE)
  }

  # (A3) 遍历 idents，获取对应的cell id，返回list
  cells.idents <- sapply(
    X = idents,
    FUN = function(i) {
      # Idents(object) 取出ident列，named vector。值为类型，名为cell id
      # Idents(object)[cells] 按cells 排序
      # Idents(pbmc) |> head(n=2) |> as.vector() #[1] "Naive CD4 T" "B"  丢掉名字，只要值
      # 是否 和idents 相等，布尔值。返回为T的cell id
      return(cells[as.vector(x = Idents(object = object)[cells]) == i])
    },
    simplify = FALSE,
    USE.NAMES = TRUE
  )

  #(A4) 如果idents中有na，则把其cell id保存到NA键值对中
  if (any(is.na(x = Idents(object = object)[cells]))) {
  	# Idents(object = object) #1.全部cell id
	# Idents(object = object)[cells] #2.按cell排序
	# is.na(x = Idents(object = object)[cells]) #3.是否是na
	# which(x = is.na(x = Idents(object = object)[cells])) #4.返回不是na的下标
	# names(x = which(x = is.na(x = Idents(object = object)[cells]))) #5.获取其names
    cells.idents[["NA"]] <- names(x = which(x = is.na(x = Idents(object = object)[cells])))
  }

  #返回
  return(cells.idents)
}

